#include "system.h"


u8 uart1_rx_len = 0;
u8 uart2_rx_len = 0;
u8 uart4_rx_len = 0;
u8 uart1_net_buf[UART1_RX_BUF];
u8 uart2_485_buf[UART2_RX_BUF];
u8 uart4_pm25_buf[UART4_RX_BUF];


void fldrv_uart_init(void)
{
	gpio_init_type gpio_init_struct;

  /* enable the usart1 and gpio clock */
  crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
	crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, TRUE);
	crm_periph_clock_enable(CRM_USART3_PERIPH_CLOCK, TRUE);
	crm_periph_clock_enable(CRM_USART4_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  gpio_default_para_init(&gpio_init_struct);

  /* configure the usart1 tx/rx pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
	gpio_init_struct.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3 |\
														   GPIO_PINS_6 | GPIO_PINS_7 | GPIO_PINS_9 | GPIO_PINS_10;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(GPIOA, &gpio_init_struct);

  /* config usart iomux */
	gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE0, GPIO_MUX_4);	//UART4 -> PM2.5 & VOC
  gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE1, GPIO_MUX_4);
//	
	gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE2, GPIO_MUX_1);	//UART2 -> RS485
  gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE3, GPIO_MUX_1);
	
	gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_3);	//UART3 -> DIS
  gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_3);
	
  gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE9, GPIO_MUX_1);	//UART1 -> 4G
  gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE10, GPIO_MUX_1);

  /* config usart nvic interrupt */
  nvic_irq_enable(USART1_IRQn, 2, 0);
	nvic_irq_enable(USART2_IRQn, 3, 0);
	nvic_irq_enable(USART4_3_IRQn, 4, 0);

  /* configure usart param */
  usart_init(USART1, UART1_BAUDRATE, USART_DATA_8BITS, USART_STOP_1_BIT);
	usart_init(USART2, UART2_BAUDRATE, USART_DATA_8BITS, USART_STOP_1_BIT);
	usart_init(USART3, UART3_BAUDRATE, USART_DATA_8BITS, USART_STOP_1_BIT);
	usart_init(USART4, UART4_BAUDRATE, USART_DATA_8BITS, USART_STOP_1_BIT);
  usart_transmitter_enable(USART1, TRUE);
	usart_transmitter_enable(USART2, TRUE);
	usart_transmitter_enable(USART3, TRUE);
	usart_transmitter_enable(USART4, TRUE);
  usart_receiver_enable(USART1, TRUE);
	usart_receiver_enable(USART2, TRUE);
	usart_receiver_enable(USART3, TRUE);
	usart_receiver_enable(USART4, TRUE);

  /* enableusart1 interrupt */
  usart_interrupt_enable(USART1, USART_RDBF_INT, TRUE);
  usart_enable(USART1, TRUE);
//	
//	/* enableusart1 interrupt */
  usart_interrupt_enable(USART2, USART_RDBF_INT, TRUE);
  usart_enable(USART2, TRUE);
//	
	/* enableusart1 interrupt */
  usart_interrupt_enable(USART3, USART_RDBF_INT, TRUE);
  usart_enable(USART3, TRUE);
	
//	/* enableusart1 interrupt */
  usart_interrupt_enable(USART4, USART_RDBF_INT, TRUE);
  usart_enable(USART4, TRUE);
}

//计算校验和
uint8_t fldrv_check_sum(u8 *buf, u8 len)
{
	uint8_t sum = 0;
	uint8_t i = 0;

	for (i = 0; i < len; i++)
	{
		sum += buf[i];
	}

	return sum;
}

void fldrv_uart_rx_int(uint8_t rx_data,fldrv_uart_port_e uart_port)
{
	switch(uart_port)
	{
		case UART1_PORT:
			if((UART1_HEAD == rx_data) && (uart1_rx_len == 0))
			{
				uart1_net_buf[uart1_rx_len] = rx_data;
				uart1_rx_len++;
			}
			else{
				if(uart1_rx_len == FALSE)	uart1_rx_len = 0;
				else
				{
					uart1_net_buf[uart1_rx_len] = rx_data;
					uart1_rx_len++;
					if(uart1_rx_len >= UART1_RX_BUF)
					{
						uart1_rx_len = 0;
						if(uart1_net_buf[UART1_RX_BUF - 1] == fldrv_check_sum(uart1_net_buf,UART1_RX_BUF - 1))
						{
							xQueueSendFromISR(net_rd_queue,uart1_net_buf,pdFALSE);
						}
					}
				}
			}
			break;
		case UART2_PORT:
			if((DEFAULT_RS485_HEAD1 == rx_data) && (uart2_rx_len == 0))
			{
				uart2_485_buf[uart2_rx_len] = rx_data;
				uart2_rx_len++;
			}
			else if((DEFAULT_RS485_HEAD2 == rx_data) && (uart2_rx_len == 1))
			{
				uart2_485_buf[uart2_rx_len] = rx_data;
				uart2_rx_len++;
			}
			else{
				if(uart2_rx_len < 2)	uart2_rx_len = 0;
				else
				{
					uart2_485_buf[uart2_rx_len] = rx_data;
					uart2_rx_len++;
					switch(flapp_get_device_type())
					{
						case DEVICE_UNKNOWN:
							break;
						case DEVICE_MASTER:
							if(uart2_rx_len >= RS485_MISO_ENUM_END)
							{
								uart2_rx_len = 0;
								if(uart2_485_buf[RS485_MISO_CHECKNUM] == fldrv_check_sum(uart2_485_buf,RS485_MISO_CHECKNUM))
								{
									xQueueSendFromISR(rs485_queue,uart2_485_buf,pdFALSE);
								}
							}
							break;
						case DEVICE_SLAVE:
							if((DEVICE_SLAVE == rx_data) && (uart2_rx_len == 3))		//从机不接收其他从机的数据
								uart2_rx_len = 0;
							if(uart2_rx_len >= RS485_MOSI_ENUM_END)
							{
								uart2_rx_len = 0;
								if(uart2_485_buf[RS485_MOSI_CHECKNUM] == fldrv_check_sum(uart2_485_buf,RS485_MOSI_CHECKNUM))
								{
									xQueueSendFromISR(rs485_queue,uart2_485_buf,pdFALSE);
								}
							}
							break;
					}
				}
			}
			break;
		case UART3_PORT:		//显示
			break;
		case UART4_PORT:
			if((UART4_HEAD_NUM1 == rx_data) && (uart4_rx_len == 0))
			{
				uart4_pm25_buf[uart4_rx_len] = rx_data;
				uart4_rx_len++;
			}
			else if((UART4_HEAD_NUM2 == rx_data) && (uart4_rx_len == 1))
			{
				uart4_pm25_buf[uart4_rx_len] = rx_data;
				uart4_rx_len++;
			}
			else{
				if(uart4_rx_len < 2)	uart4_rx_len = 0;
				else
				{
					uint16_t air_buf[2];
					uart4_pm25_buf[uart4_rx_len] = rx_data;
					uart4_rx_len++;
					if(uart4_rx_len >= UART4_RX_BUF)
					{
						uart4_rx_len = 0;
						air_buf[0] = (((uart4_pm25_buf[9] << 8) + uart4_pm25_buf[10]) >> 1);
						air_buf[1] = (((uart4_pm25_buf[3] << 8) + uart4_pm25_buf[4]) >> 3);
						if(air_buf[0] > PM25_MAX)	air_buf[0] = PM25_MAX;
						if(air_buf[1] > VOC_MAX)	air_buf[1] = VOC_MAX;
						xQueueSendFromISR(air_quality_queue,air_buf,pdFALSE);
					}
				}
			}
			break;
	}
}

void fldrv_uart_send_buf(usart_type* usart_x,uint8_t* data,uint8_t len)
{
	uint8_t i;
	for (i=0; i<len; i++)
	{
		while(usart_flag_get(usart_x, USART_TDBE_FLAG) == RESET);
		usart_data_transmit(usart_x, data[i]);
	}
	//if(usart_x != USART2)
		vTaskDelay(TASK_UART_SEND_DLY);	//显示的时候需要间隔20ms发送
}

